package com.ec.edu.common.hello;

import com.ec.edu.common.constants.NettyConstant;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.socket.SocketChannel;
import io.netty.util.Timeout;
import io.netty.util.Timer;
import io.netty.util.TimerTask;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

/**
 *  重连检测狗，当发现当前的链路不稳定关闭之后，进行12次重连
 */
@Slf4j
@ChannelHandler.Sharable
public abstract class ConnectionWatchdog extends ChannelInboundHandlerAdapter implements TimerTask, ChannelHandlerHolder {
    private final Bootstrap bootstrap;
    private final Timer timer;
    private final int port;

    private final String host;

    private volatile boolean reconnect;
    private int attempts = 0;

    public ConnectionWatchdog(Bootstrap bootstrap, Timer timer, int port, String host, boolean reconnect) {
        this.bootstrap = bootstrap;
        this.timer = timer;
        this.port = port;
        this.host = host;
        this.reconnect = reconnect;
    }

    /**
     * channel链路每次active的时候，将其连接的次数重新☞ 0
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("-------客户端上线----------");
        HelloNettyClient.socketChannel = (SocketChannel) ctx.channel();
        log.info("当前链路已经激活了，重连尝试次数重新置为0");
        attempts = 0;
        ctx.fireChannelActive();
//        super.channelActive(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("-------客户端下线----------");
        boolean isChannelActive = true;
        if(null == HelloNettyClient.socketChannel || !HelloNettyClient.socketChannel.isActive()){
            isChannelActive = false;
        }
        if(reconnect && !isChannelActive){
            log.info("链接关闭，将进行重连");
            if (attempts < NettyConstant.RET_CONNECT_TIME) {
                int timeout = 10;
                timer.newTimeout(this, timeout, TimeUnit.SECONDS);
            }
        }
        else {
            log.info("链接关闭");
        }
//        super.channelInactive(ctx);
    }

    public void run(Timeout timeout) throws Exception {
        ChannelFuture future;
        //bootstrap已经初始化好了，只需要将handler填入就可以了
        synchronized (bootstrap) {
            bootstrap.handler(new ChannelInitializer<Channel>() {

                @Override
                protected void initChannel(Channel channel) throws Exception {
                    channel.pipeline().addLast(handlers());
                }
            });
            future = bootstrap.connect(host,port);
        }
        //future对象监听
        future.addListener(new ChannelFutureListener() {

            @Override
            public void operationComplete(ChannelFuture channelFuture) throws Exception {
                boolean succeed = channelFuture.isSuccess();
                Channel channel = channelFuture.channel();
                if (!succeed) {
                    log.info("重连失败");
                    channel.pipeline().fireChannelInactive();
                }else{
                    log.info("重连成功");
                }
            }
        });
    }
}
